home *** CD-ROM | disk | FTP | other *** search
/ HamCall (April 1991) / HAMCALL CD-ROM (Buckmaster)(April 1991).BIN / prgming / ctutor / chap12.txt < prev    next >
Text File  |  1990-10-14  |  24KB  |  530 lines

  1.  
  2.                                                     Chapter 12
  3.  
  4.                                             DYNAMIC ALLOCATION
  5.  
  6.  
  7.  
  8. WHAT IS DYNAMIC ALLOCATION?
  9. ______________________________________________________________
  10.  
  11. Dynamic allocation is very intimidating to a     =============
  12. person the first time he comes across it, but      DYNLIST.C
  13. that need not be.  Simply relax and read this    =============
  14. chapter carefully and you will have a good
  15. grounding in a very valuable programming resource.  All of the
  16. variables in every program up to this point have been static
  17. variables as far as we are concerned.  (Actually, some of them
  18. have been "automatic" and were dynamically allocated for you
  19. by the system, but it was transparent to you.)  In this
  20. chapter, we will study some dynamically allocated variables.
  21. They are variables that do not exist when the program is
  22. loaded, but are created dynamically as they are needed.  It
  23. is possible, using these techniques, to create as many
  24. variables as needed, use them, and deallocate their space for
  25. use by other variables.  As usual, the best teacher is an
  26. example, so examine the program named DYNLIST.C.
  27.  
  28. We begin by defining a named structure "animal" with a few
  29. fields pertaining to dogs.  We do not define any variables of
  30. this type, only three pointers.  If you search through the
  31. remainder of the program, you will find no variables defined
  32. so we have nothing to store data in.  All we have to work with
  33. are three pointers, each of which point to the defined
  34. structure.  In order to do anything, we need some variables,
  35. so we will create some dynamically.
  36.  
  37.  
  38. DYNAMIC VARIABLE CREATION
  39. ______________________________________________________________
  40.  
  41. The first program statement, which assigns something to the
  42. pointer "pet1" will create a dynamic structure containing
  43. three variables.  The heart of the statement is the "malloc"
  44. function buried in the middle of the statement.  This is a
  45. memory allocate function that needs the other things to
  46. completely define it.  The malloc function, by default, will
  47. allocate a piece of memory on a heap that is "n" characters
  48. in length and will be of type character.  The "n" must be
  49. specified as the only argument to the function.  We will
  50. discuss "n" shortly, but first we need to define a heap.
  51.  
  52.  
  53. WHAT IS A HEAP?
  54. ______________________________________________________________
  55.  
  56. Every compiler has a set of limitations on it as to how big
  57. the executable file can be, how many variables can be used,
  58.  
  59.                                                           12-1
  60.  
  61.                                Chapter 12 - Dynamic Allocation
  62.  
  63. how long the source file can be, etc.  One limitation placed
  64. on users by most MS-DOS C compilers is a limit of 64K for the
  65. executable code if you happen to be in the small memory model.
  66. This is because the IBM-PC uses a microprocessor with a 64K
  67. segment size, and it requires special calls to use data
  68. outside of a single segment.  In order to keep the program
  69. small and efficient, these calls are not used in some MS-DOS
  70. implementations of C, and the memory space is limited but
  71. still adequate for most programs.
  72.  
  73. A heap is an area outside of this 64K boundary which can be
  74. accessed by the program to store data and variables.  The data
  75. and variables are put on the heap by the system as calls to
  76. malloc are made.  The system keeps track of where the data is
  77. stored.  Data and variables can be deallocated as desired
  78. leading to holes in the heap.  The system knows where the
  79. holes are and will use them for additional data storage as
  80. more malloc calls are made.  The structure of the heap is
  81. therefore a very dynamic entity, changing constantly.
  82.  
  83.  
  84. MORE ABOUT SEGMENTS
  85. ______________________________________________________________
  86.  
  87. Most C compilers give the user a choice of memory models to
  88. use.  The user has a choice of using a model with a 64K
  89. limitation for either program or data leading to a small fast
  90. program or selecting a 640K limitation and requiring longer
  91. address calls leading to less efficient addressing.  Using the
  92. larger address space requires inter segment addressing,
  93. resulting in the slightly slower running time.  The time is
  94. probably insignificant in most programs, but there are other
  95. considerations.
  96.  
  97. If a program uses no more than 64K bytes for the total of its
  98. code and memory and if it doesn't use a stack, it can be made
  99. into a .COM file.  Since a .COM file is already in a memory
  100. image format, it can be loaded very quickly whereas a file in
  101. an .EXE format must have its addresses relocated as it is
  102. loaded.  Therefore a tiny memory model can generate a program
  103. that loads faster than one generated with a larger memory
  104. model.  Don't let this worry you, it is a fine point that few
  105. programmers worry about.
  106.  
  107. Using dynamic allocation, it is possible to store the data on
  108. the heap and that may be enough to allow you to use the small
  109. memory model.  Of course, you wouldn't store local variables
  110. such as counters and indexes on the heap, only very large
  111. arrays or structures.
  112.  
  113. Even more important than the need to stay within the small
  114. memory model is the need to stay within the computer.  If you
  115. had a program that used several large data storage areas, but
  116. not at the same time, you could load one block storing it
  117.  
  118.                                                           12-2
  119.  
  120.                                Chapter 12 - Dynamic Allocation
  121.  
  122. dynamically, then get rid of it and reuse the space for the
  123. next large block of data.  Dynamically storing each block of
  124. data in succession, and using the same storage for each block
  125. may allow you to run your entire program in the computer
  126. without breaking it up into smaller programs.
  127.  
  128.  
  129. BACK TO THE MALLOC FUNCTION
  130. ______________________________________________________________
  131.  
  132. Hopefully the above description of the heap and the overall
  133. plan for dynamic allocation helped you to understand what we
  134. are doing with the malloc function.  It simply asks the system
  135. for a block of memory of the size specified, and gets the
  136. block with the pointer pointing to the first element of the
  137. block.  The only argument in the parentheses is the size of
  138. the block desired and in our present case, we desire a block
  139. that will hold one of the structures we defined at the
  140. beginning of the program.  The "sizeof" operator is new, new
  141. to us at least.  It returns the size in bytes of the argument
  142. within its parentheses.  It therefore, returns the size of the
  143. structure named "animal", in bytes, and that number is sent
  144. to the system with the malloc call.  At the completion of that
  145. call, we have a block on the heap allocated to us, with "pet1"
  146. pointing to the block of data.
  147.  
  148.  
  149. WHAT IS A CAST?
  150. ______________________________________________________________
  151.  
  152. We still have a funny looking construct at the beginning of
  153. the malloc function call.  That is called a "cast".  The
  154. malloc function returns a block with the pointer pointing to
  155. it being a pointer to type char by default.  Many times, if
  156. not most, you do not want a pointer to a char type variable,
  157. but to some other type.  You can define the pointer type with
  158. the construct given on the example line.  In this case we want
  159. the pointer to point to a structure of type animal, so we tell
  160. the compiler with this strange looking construct.  Even if you
  161. omit the cast, most compilers will return a pointer correctly,
  162. give you a warning, and go on to produce a working program.
  163. It is better programming practice to provide the compiler with
  164. the cast to prevent getting the warning message.  The data
  165. space of the computer is depicted graphically by figure 12-1.
  166.  
  167.  
  168. USING THE DYNAMICALLY ALLOCATED STRUCTURE
  169. ______________________________________________________________
  170.  
  171. If you remember our studies of structures and pointers, you
  172. will recall that if we have a structure with a pointer
  173. pointing to it, we can access any of the variables within the
  174. structure.  In the next three lines of the program, we assign
  175. some silly data to the structure for illustration.  It should
  176.  
  177.                                                           12-3
  178.  
  179.                                Chapter 12 - Dynamic Allocation
  180.  
  181. come as no surprise to you that these assignment statements
  182. look just like assignments to statically defined variables.
  183. Figure 12-2 illustrates the state of the data space at this
  184. point in the program execution.
  185.  
  186. In the next statement, we assign the value of "pet1" to "pet2"
  187. also.  This creates no new data, we simply have two pointers
  188. to the same object.  Since "pet2" is pointing to the structure
  189. we created above, "pet1" can be reused to get another
  190. dynamically allocated structure which is just what we do next.
  191. Keep in mind that "pet2" could have just as easily been used
  192. for the new allocation.  The new structure is filled with
  193. silly data for illustration.
  194.  
  195.  
  196. Finally, we allocate another block on the heap using the
  197. pointer "pet3", and fill its block with illustrative data.
  198. Figure 12-3 illustrates the condition of the data space
  199. following execution of line 25 of the program.
  200.  
  201. Printing the data out should pose no problem to you since
  202. there is nothing new in the three print statements.  It is
  203. left for you to study.
  204.  
  205. Even though it is not illustrated in this tutorial, you can
  206. dynamically allocate and use simple variables such as a single
  207. "char" type variable.  This should be discouraged however
  208. since it is very inefficient.
  209.  
  210.  
  211. GETTING RID OF THE DYNAMICALLY ALLOCATED DATA
  212. ______________________________________________________________
  213.  
  214. Another new function is used to get rid of the data and free
  215. up the space on the heap for reuse, the function "free".  To
  216. use it, you simply call it with the pointer to the block as
  217. the only argument, and the block is deallocated.
  218.  
  219. In order to illustrate another aspect of the dynamic
  220. allocation and deallocation of data, an additional step is
  221. included in the program on your monitor.  The pointer "pet1"
  222. is assigned the value of "pet3" in line 38.  In doing this,
  223. the block that "pet1" was pointing to is effectively lost
  224. since there is no pointer that is now pointing to that block.
  225. It can therefore never again be referred to, changed, or
  226. disposed of.  That memory, which is a block on the heap, is
  227. wasted from this point on.  This is not something that you
  228. would ever purposely do in a program.  It is only done here
  229. for illustration.
  230.  
  231. The first free function call removes the block of data that
  232. "pet1" and "pet3" were pointing to, and the second free call
  233. removes the block of data that "pet2" was pointing to.  We
  234. therefore have lost access to all of our data generated
  235.  
  236.                                                           12-4
  237.  
  238.                                Chapter 12 - Dynamic Allocation
  239.  
  240. earlier.  There is still one block of data that is on the heap
  241. but there is no pointer to it since we lost the address to it.
  242. Figure 12-4 illustrates the data space as it now appears.
  243. Trying to free the data pointed to by "pet1" would result in
  244. an error because it has already been freed by the use of
  245. "pet3".  There is no need to worry, when we return to DOS, the
  246. entire heap will be disposed  of with no regard to what we
  247. have put on it.  The point does need to made that, if you lose
  248. a pointer to a block of the heap, it forever removes that
  249. block of data storage from our use and we may need that
  250. storage later.
  251.  
  252. Compile and run the program to see if it does what you think
  253. it should do based on this discussion.
  254.  
  255.  
  256. THAT WAS A LOT OF DISCUSSION
  257. ______________________________________________________________
  258.  
  259. It took six pages to get through the discussion of the last
  260. program but it was time well spent.  It should be somewhat
  261. exciting to you to know that there is nothing else to learn
  262. about dynamic allocation, the last four pages covered it all.
  263. Of course, there is a lot to learn about the technique of
  264. using dynamic allocation, and for that reason, there are two
  265. more example programs to study.  But the fact remains, there
  266. is nothing more to learn about dynamic allocation than what
  267. was given so far in this chapter.
  268.  
  269.  
  270. AN ARRAY OF POINTERS
  271. ______________________________________________________________
  272.  
  273. Load and display the file BIGDYNL.C for          =============
  274. another example of dynamic allocation.  This       BIGDYNL.C
  275. program is very similar to the last one since    =============
  276. we use the same structure, but this time we
  277. define an array of pointers to illustrate the means by which
  278. you could build a large database using an array of pointers
  279. rather than a single pointer to each element.  To keep it
  280. simple we define 12 elements in the array and another working
  281. pointer named "point".
  282.  
  283. The "*pet[12]" is new to you so a few words would be in order.
  284. What we have defined is an array of 12 pointers, the first
  285. being "pet[0]", and the last "pet[11]".  Actually, since an
  286. array is itself a pointer, the name "pet" by itself is a
  287. pointer to a pointer.  This is valid in C, and in fact you can
  288. go farther if needed but you will get quickly confused.  I
  289. know of no limit as to how many levels of pointing are
  290. possible, so a definition such as "int ****pt" is legal as a
  291. pointer to a pointer to a pointer to a pointer to an integer
  292. type variable, if I counted right.  Such usage is discouraged
  293. until you gain considerable experience.
  294.  
  295.                                                           12-5
  296.  
  297.                                Chapter 12 - Dynamic Allocation
  298.  
  299. Now that we have 12 pointers which can be used like any other
  300. pointer, it is a simple matter to write a loop to allocate a
  301. data block dynamically for each and to fill the respective
  302. fields with any data desirable.  In this case, the fields are
  303. filled with simple data for illustrative purposes, but we
  304. could be reading in a database, readings from some test
  305. equipment, or any other source of data.
  306.  
  307. A few fields are randomly picked to receive other data to
  308. illustrate that simple assignments can be used, and the data
  309. is printed out to the monitor.  The pointer "point" is used
  310. in the printout loop only to serve as an illustration, the
  311. data could have been easily printed using the "pet[n]" means
  312. of definition.  Finally, all 12 blocks of data are freed
  313. before terminating the program.
  314.  
  315. Compile and run this program to aid in understanding this
  316. technique.  As stated earlier, there was nothing new here
  317. about dynamic allocation, only about an array of pointers.
  318.  
  319.  
  320. A LINKED LIST
  321. ______________________________________________________________
  322.  
  323. We finally come to the grandaddy of all          =============
  324. programming techniques as far as being             DYNLINK.C
  325. intimidating.  Load the program DYNLINK.C for    =============
  326. an example of a dynamically allocated linked
  327. list.  It sounds terrible, but after a little time spent with
  328. it, you will see that it is simply another programming
  329. technique made up of simple components that can be a powerful
  330. tool.
  331.  
  332. In order to set your mind at ease, consider the linked list
  333. you used when you were a child.  Your sister gave you your
  334. birthday present, and when you opened it, you found a note
  335. that said, "Look in the hall closet."  You went to the hall
  336. closet, and found another note that said, "Look behind the TV
  337. set."  Behind the TV you found another note that said, "Look
  338. under the coffee pot."  You continued this search, and finally
  339. you found your pair of socks under the dogs feeding dish.
  340. What you actually did was to execute a linked list, the
  341. starting point being the wrapped present and the ending point
  342. being under the dogs feeding dish.  The list ended at the dogs
  343. feeding dish since there were no more notes.
  344.  
  345. In the program DYNLINK.C, we will be doing the same thing as
  346. your sister forced you to do.  We will however, do it much
  347. faster and we will leave a little pile of data at each of the
  348. intermediate points along the way.  We will also have the
  349. capability to return to the beginning and traverse the entire
  350. list again and again if we so desire.
  351.  
  352.                                                           12-6
  353.  
  354.                                Chapter 12 - Dynamic Allocation
  355.  
  356. THE DATA DEFINITIONS
  357. ______________________________________________________________
  358.  
  359. This program starts similarly to the last two with the
  360. addition of the definition of a constant to be used later.
  361. The structure is nearly the same as that used in the last two
  362. programs except for the addition of another field within the
  363. structure in line 11, the pointer.  This pointer is a pointer
  364. to another structure of this same type and will be used to
  365. point to the next structure in order.  To continue the above
  366. analogy, this pointer will point to the next note, which in
  367. turn will contain a pointer to the next note after that.
  368.  
  369. We define three pointers to this structure for use in the
  370. program, and one integer to be used as a counter, and we are
  371. ready to begin using the defined structure for whatever
  372. purpose we desire.  In this case, we will once again generate
  373. nonsense data for illustrative purposes.
  374.  
  375.  
  376. THE FIRST FIELD
  377. ______________________________________________________________
  378.  
  379. Using the malloc function, we request a block of storage on
  380. the heap and fill it with data.  The additional  field in this
  381. example, the pointer, is assigned the value of NULL, which is
  382. only used to indicate that this is the end of the list.  We
  383. will leave the pointer "start" at this structure, so that it
  384. will always point to the first structure of the list.  We also
  385. assign "prior" the value of "start" for reasons we will see
  386. soon.  Keep in mind that the end points of a linked list will
  387. always have to be handled differently than those in the middle
  388. of a list.  We have a single element of our list now and it
  389. is filled with representative data.  Figure 12-5 is the
  390. graphical representation of the data space following execution
  391. of line 22.
  392.  
  393.  
  394. FILLING ADDITIONAL STRUCTURES
  395. ______________________________________________________________
  396.  
  397. The next group of assignments and control statements are
  398. included within a "for" loop so we can build our list fast
  399. once it is defined.  We will go through the loop a number of
  400. times equal to the constant "RECORDS" defined at the beginning
  401. of our program.  Each time through, we allocate memory, fill
  402. the first three fields with nonsense, and fill the pointers.
  403. The pointer in the last record is given the address of this
  404. new record because the "prior" pointer is pointing to the
  405. prior record.  Thus "prior->next" is given the address of the
  406. new record we have just filled.  The pointer in the new record
  407. is assigned the value NULL, and the pointer "prior" is given
  408. the address of this new record because the next time we create
  409. a record, this one will be the prior one at that time.  That
  410.  
  411.                                                           12-7
  412.  
  413.                                Chapter 12 - Dynamic Allocation
  414.  
  415. may sound confusing but it really does make sense if you spend
  416. some time studying it.
  417.  
  418. Figure 12-6 illustrates the data space following execution of
  419. the loop two times.  The list is growing downward by one
  420. element each time we execute the statements in the loop.  When
  421. we have gone through the "for" loop 6 times, we will have a
  422. list of 7 structures including the one we generated prior to
  423. the loop.  The list will have the following characteristics.
  424.  
  425. 1.   "start" points to the first structure in the list.
  426.  
  427. 2.   Each structure contains a pointer to the next structure.
  428.  
  429. 3.   The last structure has a pointer that points to NULL and
  430.      can be used to detect the end.
  431.  
  432. It should be clear to you, if you understand the overall data
  433. structure, that it is not possible to simply jump into the
  434. middle of the list and change a few values.  The only way to
  435. get to the third structure is by starting at the beginning and
  436. working your way down through the list one record at a time.
  437. Although this may seem like a large price to pay for the
  438. convenience of putting so much data outside of the program
  439. area, it is actually a very good way to store some kinds of
  440. data.
  441.  
  442. A word processor would be a good application for this type of
  443. data structure because you would never need to have random
  444.  
  445. access to the data.  In actual practice, this is the basic
  446. type of storage used for the text in a word processor with
  447. one line of text per record.  Actually, a program with any
  448. degree of sophistication would use a doubly linked list.  This
  449. would be a list with two pointers per record, one pointing
  450. down to the next record, and the other pointing up to the
  451. record just prior to the one in question.  Using this kind of
  452. a record structure would allow traversing the data in either
  453. direction.
  454.  
  455.  
  456. PRINTING THE DATA OUT
  457. ______________________________________________________________
  458.  
  459. To print the data out, a similar method is used as that used
  460. to generate the data.  The pointers are initialized and are
  461. then used to go from record to record reading and displaying
  462. each record one at a time.  Printing is terminated when the
  463. NULL on the last record is found, so the program doesn't even
  464. need to know how many records are in the list.  Finally, the
  465. entire list is deleted to make room in memory for any
  466. additional data that may be needed, in this case, none.  Care
  467. must be taken to assure that the last record is not deleted
  468. before the NULL is checked.  Once the data is gone, it is
  469. impossible to know if you are finished yet.
  470.  
  471.                                                           12-8
  472.  
  473.                                Chapter 12 - Dynamic Allocation
  474.  
  475. MORE ABOUT DYNAMIC ALLOCATION AND LINKED LISTS
  476. ______________________________________________________________
  477.  
  478. It is not difficult, and it is not trivial, to add elements
  479. into the middle of a linked list.  It is necessary to create
  480. the new record, fill it with data, and point its pointer to
  481. the record it is desired to precede.  If the new record is to
  482. be installed between the 3rd and 4th, for example, it is
  483. necessary for the new record to point to the 4th record, and
  484. the pointer in the 3rd record must point to the new one.
  485. Adding a new record to the beginning or end of a list are each
  486. special cases.  Consider what must be done to add a new record
  487. in a doubly linked list.
  488.  
  489. Entire books are written describing different types of linked
  490. lists and how to use them, so no further detail will be given.
  491. The amount of detail given should be sufficient for a
  492. beginning understanding of C and its capabilities.
  493.  
  494.  
  495. ANOTHER NEW FUNCTION - CALLOC
  496. ______________________________________________________________
  497.  
  498. One more function must be mentioned, the "calloc" function.
  499. This function allocates a block of memory and clears it to all
  500. zeros which may be useful in some circumstances.  It is
  501. similar to "malloc" and will be left as an exercise for you
  502. to read about and use "calloc" if you desire.
  503.  
  504.  
  505. PROGRAMMING EXERCISES
  506. ______________________________________________________________
  507.  
  508. 1.   Rewrite the example program STRUCT1.C from chapter 11 to
  509.      dynamically allocate the two structures.
  510.  
  511. 2.   Rewrite the example program STRUCT2.C from chapter 11 to
  512.      dynamically allocate the 12 structures.
  513.  
  514.  
  515.  
  516.  
  517. Note; The figures referred to in this chapter are graphics
  518.       which are impossible to include in a text file.  Since
  519.       there is no way to include them, we have made it possi-
  520.       ble for you to obtain a copy of these figures.  See the
  521.       READ.ME file for details.
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.                                                           12-9
  529.  
  530.